#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>

#define PORT 8080

void *connection_handler(void *);

int main() {
    int sockfd, newsockfd;
    struct sockaddr_in serv_addr, cli_addr;
    socklen_t clilen;
    pthread_t thread_id;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("ERROR opening socket");
        exit(1);
    }

    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(PORT);

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
        perror("ERROR on binding");
        exit(1);
    }

    listen(sockfd, 5);
    clilen = sizeof(cli_addr);

    while (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen)) {
        if (pthread_create(&thread_id, NULL, connection_handler, (void*) &newsockfd) < 0) {
            perror("ERROR on thread creation");
            return 1;
        }
    }

    if (newsockfd < 0) {
        perror("ERROR on accept");
        exit(1);
    }

    close(sockfd);
    return 0;
}

void *connection_handler(void *socket_desc) {
    int sock = *(int*)socket_desc;
    char buffer[256];
    int read_size;

    while ((read_size = read(sock, buffer, sizeof(buffer))) > 0) {
        printf("Here is the message from %d: %s\n",sock ,buffer);
        bzero(buffer, sizeof(buffer));
    }

    if (read_size == 0) {
        printf("Client disconnected\n");
    } else if (read_size < 0) {
        perror("ERROR reading from socket");
    }
    return 0;
}
